package oss

import (
	"context"
	"encoding/json"
	"github.com/qiniu/go-sdk/v7/auth"
	"github.com/qiniu/go-sdk/v7/auth/qbox"
	"github.com/qiniu/go-sdk/v7/storage"
	"mime/multipart"
	"strings"
	"time"
)

type QiniuOss struct {
	Domain          string
	Zone            string
	Bucket          string
	AccessKey       string
	SecretKey       string
	UseHttps        bool
	UseCdnDomains   bool
	ClientUploadUrl string
}

func NewQiniuOss(config string) *QiniuOss {
	var qiniu QiniuOss
	json.Unmarshal([]byte(config), &qiniu)
	return &qiniu
}

// 上传
func (p QiniuOss) Upload(file *multipart.FileHeader, key string) string {
	putPlicy := storage.PutPolicy{
		Scope: p.Bucket,
	}
	mac := qbox.NewMac(p.AccessKey, p.SecretKey)

	upToken := putPlicy.UploadToken(mac)

	formUploader := storage.NewFormUploader(p.qiniuConfig())

	ret := storage.PutRet{}        // 上传后返回的结果
	putExtra := storage.PutExtra{} // 额外参数

	f, openError := file.Open()
	if openError != nil {
		panic(openError)
	}
	defer f.Close()

	if err := formUploader.Put(context.Background(), &ret, upToken, strings.TrimLeft(key, "/"), f, file.Size, &putExtra); err != nil {
		panic(err)
	}
	return p.Domain + key
}

// 删除图片
func (p QiniuOss) DeleteFile(key string) bool {
	mac := qbox.NewMac(p.AccessKey, p.SecretKey)
	cfg := p.qiniuConfig()
	bucketManager := storage.NewBucketManager(mac, cfg)
	if err := bucketManager.Delete(p.Bucket, key); err != nil {
		panic(err)
	}
	return true
}

// 获取机房位置
func (p QiniuOss) qiniuConfig() *storage.Config {
	cfg := storage.Config{
		UseHTTPS:      p.UseHttps,
		UseCdnDomains: p.UseCdnDomains,
	}
	switch p.Zone { // 根据配置文件进行初始化空间对应的机房
	case "ZoneHuadong":
		cfg.Zone = &storage.ZoneHuadong
	case "ZoneHuabei":
		cfg.Zone = &storage.ZoneHuabei
	case "ZoneHuanan":
		cfg.Zone = &storage.ZoneHuanan
	case "ZoneBeimei":
		cfg.Zone = &storage.ZoneBeimei
	case "ZoneXinjiapo":
		cfg.Zone = &storage.ZoneXinjiapo
	}
	return &cfg
}

// 获取客户端上传配置信息
func (p QiniuOss) GetCliendConfig(key string) map[string]interface{} {
	mac := auth.New(p.AccessKey, p.SecretKey)
	putPolicy := storage.PutPolicy{
		Scope: p.Bucket,
	}
	putPolicy.Expires = uint64(time.Now().Add(time.Hour).Unix())
	data := map[string]interface{}{
		"serverurl": p.ClientUploadUrl,
		"domain":    p.Domain,
		"token":     putPolicy.UploadToken(mac),
		"key":       key,
		"type":      "qiniu",
	}
	return data
}
